﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;

namespace MvcControlToolkit
{
    /// <summary>
    /// ResizableControl is an extender that attaches to any element on a web page 
    /// and allows the user to resize that control with a handle that attaches to 
    /// lower-right corner of the control. 
    /// 
    /// The resize handle lets the user resize the element as if it were a window. 
    /// The appearance of the resize handle can be specified by the page designer 
    /// with a CSS style. The content within the element can use CSS styles to 
    /// automatically resize to fit the new dimensions.
    /// </summary>
    public static class ResizableControlExtensions
    {
        private static readonly int DEFAULT_MAX = 100000;

        /// <summary>
        /// Creates a ResizableControl extender
        /// </summary>
        /// <param name="elementId">The ID of the element that becomes resizable</param>
        /// <param name="handleCssClass">The name of the CSS class to apply to the resize handle</param>
        public static string ResizableControl(this AjaxHelper helper, string elementId, string handleCssClass)
        {
            return helper.ResizableControl(elementId, handleCssClass, 0, 0, DEFAULT_MAX, DEFAULT_MAX);
        }

        /// <summary>
        /// Creates a ResizableControl extender with the specified properties
        /// </summary>
        /// <param name="elementId">The ID of the element that becomes resizable</param>
        /// <param name="handleCssClass">The name of the CSS class to apply to the resize handle</param>
        /// <param name="minWidth">Minimum width of the resizable element </param>
        /// <param name="minHeight">Minimum height of the resizable element </param>
        /// <param name="maxWidth">Maximum width of the resizable element</param>
        /// <param name="maxHeight">Maximum height of the resizable element</param>
        public static string ResizableControl(this AjaxHelper helper, string elementId, string handleCssClass, int minWidth, int minHeight, int maxWidth, int maxHeight)
        {
            return helper.ResizableControl(
                    elementId,
                    handleCssClass, 
                    "",
                    minWidth, 
                    minHeight,
                    maxWidth,
                    maxHeight,
                    "",
                    "",
                    "",
                    0,
                    0
                );
        }

        /// <summary>
        /// Creates a ResizableControl extender with the specified properties
        /// </summary>
        /// <param name="elementId">The ID of the element that becomes resizable</param>
        /// <param name="handleCssClass">The name of the CSS class to apply to the resize handle</param>
        /// <param name="resizableCssClass">The name of the CSS class to apply to the element when resizing</param>
        /// <param name="minWidth">Minimum width of the resizable element </param>
        /// <param name="minHeight">Minimum height of the resizable element </param>
        /// <param name="maxWidth">Maximum width of the resizable element</param>
        /// <param name="maxHeight">Maximum height of the resizable element</param>
        /// <param name="onClientResizeBegin">Event fired when the element starts being resized </param>
        /// <param name="onClientResizing">Event fired as the element is being resized</param>
        /// <param name="onClientResize">Event fired when the element has been resized</param>
        /// <param name="handleOffsetX">Horizontal offset to apply to the location of the resize handle</param>
        /// <param name="handleOffsetY">Vertical offset to apply to the location of the resize handle</param>
        public static string ResizableControl(this AjaxHelper helper, string elementId, string handleCssClass, string resizableCssClass, int minWidth, int minHeight, int maxWidth, int maxHeight, string onClientResizeBegin, string onClientResizing, string onClientResize, int handleOffsetX, int handleOffsetY)
        {
            //create properies
            RouteValueDictionary props = new RouteValueDictionary();
            props.Add("ClientStateFieldID", string.Format("{0}_{1}", elementId, "resizableState"));

            props.AddIfNotDefault("HandleCssClass", handleCssClass);
            props.AddIfNotDefault("ResizableCssClass", resizableCssClass);
            props.AddIfNotDefault("MinimumWidth", minWidth);
            props.AddIfNotDefault("MinimumHeight", minHeight);
            props.AddIfNotDefault("MaximumWidth", maxWidth);
            props.AddIfNotDefault("MaximumHeight", maxHeight);
            props.AddIfNotDefault("OnClientResizeBegin", onClientResizeBegin);
            props.AddIfNotDefault("OnClientResizing", onClientResizing);
            props.AddIfNotDefault("OnClientResize", onClientResize);
            props.AddIfNotDefault("HandleOffsetX", handleOffsetX);
            props.AddIfNotDefault("HandleOffsetY", handleOffsetY);

            return helper.ResizableControl(
                    elementId,
                    props
                );
        }

        /// <summary>
        /// Creates a ResizableControl extender with the specified properties
        /// </summary>
        /// <param name="elementId">The ID of the element that becomes resizable</param>
        /// <param name="properties">An object containing the properties to be set</param>
        public static string ResizableControl(this AjaxHelper helper, string elementId, object properties)
        {
            StringBuilder sb = new StringBuilder();

            // Add Microsoft Ajax library   
            sb.Append(helper.MicrosoftAjaxInclude());

            // Add toolkit scripts   
            sb.Append(helper.ToolkitInclude(
                    "AjaxControlToolkit.ExtenderBase.BaseScripts.js",
                    "AjaxControlToolkit.Common.Common.js",
                    "AjaxControlToolkit.ResizableControl.ResizableControlBehavior.js"
                ));

            sb.AppendFormat("<input type=\"hidden\" name=\"{0}_{1}\" id=\"{0}_{1}\" />", elementId, "resizableState");
            
            // Perform $create               
            sb.AppendLine(helper.Create("AjaxControlToolkit.ResizableControlBehavior", properties, elementId));

            return sb.ToString();
        }

        private static void AddProp(RouteValueDictionary dictionary, string name, int value)
        {
            if (value != default(int))
                dictionary.Add(name, value);
        }

        private static void AddProp(RouteValueDictionary dictionary, string name, string value)
        {
            if (value != default(string))
                dictionary.Add(name, value);
        }
    }
}
